/*
 * Copyright (C) 2016-2017 mzlion(mzllon@qq.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mzlion.core.binary;

import com.mzlion.core.lang.Assert;
import com.mzlion.core.lang.StringUtils;

import javax.xml.bind.DatatypeConverter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * BASE64的编码和解码工具
 *
 * @author mzlion on 2016/6/22.
 */
public class Base64 {

    private Base64() {
        throw new UnsupportedOperationException();
    }

    /**
     * 标准的BASE64编码
     *
     * @param data 待BASE64编码的字节数组
     * @return 待BASE64编码的字符串
     */
    public static String encode(final byte[] data) {
        return DatatypeConverter.printBase64Binary(data);
    }

    /**
     * 标准的BASE64编码
     *
     * @param data 待BASE64编码的字符串
     * @return BASE64之后的字符串
     */
    public static String encode(final String data) {
        return encode(data, null);
    }

    /**
     * 标准的BASE64编码
     *
     * @param data     待BASE64编码的字符串
     * @param encoding 原始数据的编码,为空时采用UTF-8编码
     * @return BASE64之后的字符串
     */
    public static String encode(final String data, final String encoding) {
        if (StringUtils.isEmpty(data)) return data;
        Charset charset = StringUtils.isEmpty(encoding) ? StandardCharsets.UTF_8 : Charset.forName(encoding);
        return DatatypeConverter.printBase64Binary(data.getBytes(charset));
    }

    /**
     * 标准的BASE64解码
     *
     * @param base64Data 已经编码过的字符串
     * @return 返回原始数据的字节数组形式
     */
    public static byte[] decode(final String base64Data) {
        Assert.hasLength(base64Data, "The Base64 data is null.");
        return DatatypeConverter.parseBase64Binary(base64Data);
    }

    /**
     * 标准的BASE64解码
     *
     * @param base64Data 已经编码过的字符串
     * @return 原始数据
     */
    public static String decode2String(final String base64Data) {
        return decode2String(base64Data, null);
    }

    /**
     * 标准的BASE64解码
     *
     * @param base64Data 已经编码过的字符串
     * @param encoding   原始数据的编码,为空时采用UTF-8编码
     * @return 原始数据
     */
    public static String decode2String(final String base64Data, final String encoding) {
        if (StringUtils.isEmpty(base64Data)) return base64Data;
        Charset charset = StringUtils.isEmpty(encoding) ? StandardCharsets.UTF_8 : Charset.forName(encoding);
        byte[] data = decode(base64Data);
        return new String(data, charset);
    }
}
